package com.vvlive.caibao.smartcity.utils.sort;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class SortUtil {

	public static Map<String, List<Name>> getListByGroup(List<String> words) {
		
		Map<String, List<Name>> map = new HashMap<>();
		String[] temp = new String[words.size()];
		// get the first letters 
		for (int i = 0; i < words.size(); i++) {
			temp[i] = Util.getFirstLetter(words.get(i));
		}
		// sort these letters
		Arrays.sort(temp); 

		CustomSortComparator sortChineseName = new CustomSortComparator();
		// add data to the Map which you wanna return
		for (String t : temp) {
			// get all the names which first letter is the current letter
			List<Name> names = getListByFirstLetter(t, words);
			// sort the names before being added to the map
			Collections.sort(names, sortChineseName);
			map.put(t, names);
		}
		return map;
	}

	/**
	 * Get the names which first letter is what you offer 
	 * from the old names
	 * @param firstLetter The first letter
	 * @param oldNames	The old names
	 * @return
	 */
	private static List<Name> getListByFirstLetter(String firstLetter, List<String> oldNames) {
		List<Name> names = new ArrayList<>();
		Name name = null;
		for (String oldName : oldNames) {
			if (firstLetter.equals(Util.getFirstLetter(oldName))) {
				name = new Name();
				name.setFirst(firstLetter);
				name.setOriginal(oldName);
				name.setWhole(Util.cn2Letter(oldName));
				names.add(name);
				name = null;
			}
		}
		return names;
	}

	private static final class Util {

		/**
		 * Get the first letter of one word
		 * 
		 * @param word
		 * @return
		 */
		public static String getFirstLetter(String word) {
			String first = getFirst(word);
			if (first.matches("[a-zA-Z]")) {
				return first.toUpperCase();
			} else if (first.matches("[\u4e00-\u9fa5]")) {
				return cn2Letter(first);
			}
			return "#";
		}

		/**
		 * Get Chinese first letters
		 * 
		 * @param chinese Chinese string
		 * @return
		 */
		public static String cn2Letter(String chinese) {
			try {
				StringBuffer buffer = new StringBuffer();
				byte b[] = chinese.getBytes("GBK");
				for (int i = 0; i < b.length; i++) {
					if ((b[i] & 255) > 128) {
						int char1 = b[i++] & 255;
						char1 <<= 8;
						int chart = char1 + (b[i] & 255);
						buffer.append(getPYIndexChar((char) chart, true));
						continue;
					}
					char c = (char) b[i];
					if (!Character.isJavaIdentifierPart(c))
						c = getFirst(chinese).toCharArray()[0];
					buffer.append(c);
				}
				return buffer.toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
			return "#";
		}
		
		private static char getPYIndexChar(char strChinese, boolean bUpCase) {
			int charGBK = strChinese;
			char result;
			if (charGBK >= 45217 && charGBK <= 45252)
				result = 'A';
			else if (charGBK >= 45253 && charGBK <= 45760)
				result = 'B';
			else if (charGBK >= 45761 && charGBK <= 46317)
				result = 'C';
			else if (charGBK >= 46318 && charGBK <= 46825)
				result = 'D';
			else if (charGBK >= 46826 && charGBK <= 47009)
				result = 'E';
			else if (charGBK >= 47010 && charGBK <= 47296)
				result = 'F';
			else if (charGBK >= 47297 && charGBK <= 47613)
				result = 'G';
			else if (charGBK >= 47614 && charGBK <= 48118)
				result = 'H';
			else if (charGBK >= 48119 && charGBK <= 49061)
				result = 'J';
			else if (charGBK >= 49062 && charGBK <= 49323)
				result = 'K';
			else if (charGBK >= 49324 && charGBK <= 49895)
				result = 'L';
			else if (charGBK >= 49896 && charGBK <= 50370)
				result = 'M';
			else if (charGBK >= 50371 && charGBK <= 50613)
				result = 'N';
			else if (charGBK >= 50614 && charGBK <= 50621)
				result = 'O';
			else if (charGBK >= 50622 && charGBK <= 50905)
				result = 'P';
			else if (charGBK >= 50906 && charGBK <= 51386)
				result = 'Q';
			else if (charGBK >= 51387 && charGBK <= 51445)
				result = 'R';
			else if (charGBK >= 51446 && charGBK <= 52217)
				result = 'S';
			else if (charGBK >= 52218 && charGBK <= 52697)
				result = 'T';
			else if (charGBK >= 52698 && charGBK <= 52979)
				result = 'W';
			else if (charGBK >= 52980 && charGBK <= 53688)
				result = 'X';
			else if (charGBK >= 53689 && charGBK <= 54480)
				result = 'Y';
			else if (charGBK >= 54481 && charGBK <= 55289)
				result = 'Z';
			else
				result = (char) (65 + (new Random()).nextInt(25));

			if (!bUpCase)
				result = Character.toLowerCase(result);

			return result;

		}

		/**
		 * Get the first char of one word
		 * 
		 * @param word
		 * @return The first char
		 */
		public static String getFirst(String word) {

			if (word == null || word.length() == 0) {
				return "#";
			} else {
				return word.substring(0, 1);
			}
		}

	}

}
